/*
 * OTA Manager implementation
 * File: ota_manager.c
 */


#include "esp_ota_ops.h"   // For esp_ota_handle_t type
#include "esp_partition.h" // For esp_partition_t type
#include "esp_https_ota.h" // For esp_https_ota_config_t type
#include "freertos/task.h" // For vTaskDelay function
#include "esp_system.h"    // For esp_restart function
#include "ota_manager.h"   // For OTA related definitions
#include "esp_log.h"       // For ESP_LOGE function
#include "network_manager.h"

// ֤�鶨��
static const char *server_cert = "-----BEGIN CERTIFICATE-----\n"
                                 "YOUR_CERTIFICATE_HERE\n"
                                 "-----END CERTIFICATE-----";

#define OTA_TAG "OTA_MGR"
static esp_ota_handle_t update_handle = 0;
static const esp_partition_t *update_partition = NULL;
static ota_status_t current_status = OTA_IDLE;

void ota_init()
{
    esp_http_client_config_t http_config = {
        .url = "192.168.0.12",
        .buffer_size = 4096,
        .cert_pem = server_cert,
        .skip_cert_common_name_check = true};

    esp_https_ota_config_t ota_config = {
        .http_config = &http_config,
        .bulk_flash_erase = true,
        .partial_http_download = false};

    esp_https_ota(&ota_config);
}

bool ota_write_data(const char *data, size_t size)
{
    if (current_status != OTA_IN_PROGRESS)
        return false;

    esp_err_t err = esp_ota_write(update_handle, data, size);
    if (err != ESP_OK)
    {
        ESP_LOGE(OTA_TAG, "Write error: 0x%x", err);
        current_status = OTA_FAIL;
        return false;
    }
    return true;
}

void ota_task(void *pvParameter)
{
    while (1)
    {
        switch (current_status)
        {
        case OTA_IN_PROGRESS:
            // ά����������
            maintain_wifi_connection();
            break;
        case OTA_SUCCESS:
            esp_ota_end(update_handle);
            esp_ota_set_boot_partition(update_partition);
            vTaskDelay(2000 / portTICK_PERIOD_MS);
            esp_restart();
            break;
        default:
            vTaskDelay(100 / portTICK_PERIOD_MS);
        }
    }
}
